package view.GUI.otherView;

import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.controlsfx.dialog.Dialogs;

import enums.GUIText;
import view.GUI.mainView.KindVBox.BoxType;
import view.GUI.mainView.MainView;
import model.Configuration;
import model.data.wrapper.InputWrapper;
import model.data.wrapper.ToPay;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;

/**
 * Provides an overview of the products that will be bought.
 * Is shown as last validation before writing to the database.
 *
 */
public final class PaycheckView extends Application {

	private final static Logger log = LogManager.getLogger("ERROR");
	// layout-boxes
	private Button btnSave;
	private Button btnCancel;
	private GridPane grid;
	private ToPay toPay;
	private MainView mainView;

	private Scene scene;
	private Stage primaryStage;
	private Window owner;
	
	private int rowCounter;
	private Label lblTitle;
	private Separator sepTop;
	private Separator sepBottom;
	private Label lblSum;
	private Label lblSumCount;
	private Label lblCustomer;

	/**
	 * Only constructor of this class.
	 * <p>
	 * Takes the message to be displayed as input as well as an owner of the popup window.
	 * 
	 * @param message Message to be displayed
	 * @param owner Window that should be blocked as long as the popup is shown
	 * @param mainView 
	 */
	public PaycheckView(ToPay toPay, Window owner, MainView mainView) {
		this.rowCounter = 0;
		this.owner = owner;
		this.primaryStage = new Stage();
		this.mainView = mainView;
		this.toPay = toPay;
		createWidgets();
		setupLayout();
		addWidgets();
		setupInteraction();

		try {
			start(primaryStage);
		} catch (Exception e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		addGoods(toPay);
	}
	
	
	private void addGoods(ToPay toPay){
		Map<BoxType, List<InputWrapper>> inputMap = toPay.getInputMap();
		int xCounter = 0;
		int yCounter = rowCounter;
		for(BoxType bt : inputMap.keySet()){			
			for(InputWrapper i: inputMap.get(bt)){
				grid.add(new Label(i.getSelectedProduct() + "(" + bt.toString() + ")" ), xCounter++, yCounter);
				switch(bt){
					case DEPOSIT:
					case DRINKS:
						grid.add(new Label(" " + String.valueOf(i.getTrayCount()) + "x " + GUIText.TRAYS.toString()), xCounter++, yCounter);
						grid.add(new Label(" " + String.valueOf(i.getBottleCount()) + "x " + GUIText.BOTTLES.toString()), xCounter++, yCounter);
						break;
					case GROCERIES:
					case OTHER:
						grid.add(new Label(" " + String.valueOf(i.getTrayCount()) + "x"), xCounter++, yCounter);
						break;
				}
				grid.add(new Label(" " + MainView.formatNumber(i.getValue())), xCounter++, yCounter);
				grid.add(new Label(" " + GUIText.DEPOSIT.toString() + ": "),xCounter++, yCounter);
				grid.add(new Label(MainView.formatNumber(i.getDepositCount())), xCounter, yCounter++);
				xCounter = 0;
			}
		}
		grid.add(lblSum, xCounter++, yCounter);
		xCounter = 3;
		lblSumCount.setText(MainView.formatNumber(toPay.getSum()));
		grid.add(lblSumCount, xCounter, yCounter++);
		grid.add(btnSave, 0, yCounter);
		grid.add(btnCancel, 1, yCounter++);
		grid.add(sepBottom, 0, yCounter);
		primaryStage.show();
	}

	private void addWidgets() {

		grid.add(lblTitle, 0, rowCounter++);
		grid.add(sepTop, 0, rowCounter++);
		grid.add(lblCustomer, 0, rowCounter++);
	}

	private void createWidgets() {

		lblSumCount = new Label();
		lblSum = new Label(GUIText.WHOLE.toString());
		lblTitle = new Label(GUIText.CHECK.toString());
		sepBottom = new Separator();
		sepTop = new Separator();
		btnSave = new Button(GUIText.SAVE.toString());
		btnCancel = new Button(GUIText.CANCEL.toString());
		grid = new GridPane();
		lblCustomer = new Label(toPay.getCustomer().getName());
	}

	/**
	 * Helper method to setup the layout.
	 */
	private void setupLayout() {

//		btnSave.setDisable(false);
		lblSumCount.getStyleClass().addAll("highlight", "double-underline");
		lblSum.setId("SumToPay");
		lblTitle.setId("topic");
		GridPane.setColumnSpan(sepBottom, 7);
		GridPane.setColumnSpan(sepTop, 7);
		grid.getStyleClass().add("grid");
		lblCustomer.setId("customer");
	}
	
	private void bookPurchase(){
		try{
			mainView.bookPurchase(toPay);					
			mainView.resetInput();
			primaryStage.close();
		} catch(IllegalArgumentException e){
			Dialogs.create()
					.message(e.getMessage())
					.showError();
		}
	}

	private void setupInteraction() {
		btnSave.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent arg0) {
				bookPurchase();
			}
		});
		btnSave.setOnKeyReleased(new EventHandler<KeyEvent>() {

			@Override
			public void handle(KeyEvent e) {
				if (e.getCode() == KeyCode.ENTER) {
					bookPurchase();
				}
			}
		});
		
		btnCancel.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent arg0) {
				primaryStage.close();
			}
		});	
	}

	@Override
	public void start(Stage primaryStage) throws Exception {
		{
			scene = new Scene(grid);
			scene.getStylesheets().add(getClass().getResource(Configuration.STYLECHECK).toExternalForm());
			scene.getStylesheets().add(getClass().getResource(Configuration.STYLEROOT).toExternalForm());
			primaryStage.initModality(Modality.WINDOW_MODAL);
			primaryStage.initOwner(owner);
			primaryStage.setScene(scene);
			primaryStage.setTitle(GUIText.CHECK.toString());
		}
	}
}
